home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Tools - Objects / MacApp / MacApp CD Release / MacApp 2.0.1 (Many Libraries) / Libraries / UPrinting.inc1.p < prev    next >
Encoding:
Text File  |  1990-10-25  |  61.0 KB  |  2,351 lines  |  [TEXT/MPS ]

  1. {$P}
  2. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
  3. { UPrinting.inc1.p }
  4. { Copyright © 1986-1990 by Apple Computer, Inc.  All rights reserved. }
  5.  
  6. {
  7.  Segmentation strategy:
  8.  
  9.  PrintRes  Resident
  10.  PrintMain Resident and used at initialization
  11.  PrintActual Used only during Actual Printing (imaging/spooling)
  12.  PrintImage    Used during imaging only
  13.  PrintSpool    Used only during printing of a Spool File
  14.  PrintDebug    Debugging code
  15.  PrintFinder Code only ever accessed from Finder Printing
  16.  PrintInit One-time Initialization Code
  17.  PrintOpen Code accessed when opening new document
  18.  PrintNonRes General non-resident code
  19.  PrintDoCommand   Code for Page Setup command
  20.  PrintTerminate   One-time-only code, called only at Termination time
  21.  
  22. }
  23.  
  24. {--------------------------------------------------------------------------------------------------}
  25. {$S PrintRes}
  26.  
  27. PROCEDURE TPrintCommand.DoIt;
  28.  
  29.     VAR
  30.         proceed:            BOOLEAN;
  31.  
  32.     BEGIN
  33.     IF fStdPrintHandler.Print(fCmdNumber, proceed) <> NIL THEN; { discard result }
  34.     END;
  35.  
  36. {--------------------------------------------------------------------------------------------------}
  37. {$S PrintSelCommand}
  38.  
  39. PROCEDURE TPrintCommand.IPrintCommand(itsCmdNumber: CmdNumber;
  40.                                       itsStdPrintHandler: TStdPrintHandler);
  41.  
  42.     BEGIN
  43.     INoChangesCommand(itsCmdNumber, itsStdPrintHandler.fDocument, itsStdPrintHandler.fView, NIL);
  44.     fStdPrintHandler := itsStdPrintHandler;
  45.     END;
  46.  
  47. {--------------------------------------------------------------------------------------------------}
  48. {$S MAFields}
  49.  
  50. PROCEDURE TPrintCommand.Fields(PROCEDURE DoToField(fieldName: Str255;
  51.                                                    fieldAddr: Ptr;
  52.                                                    fieldType: INTEGER)); OVERRIDE;
  53.  
  54.     BEGIN
  55.     DoToField('TPrintCommand', NIL, bClass);
  56.     DoToField('fStdPrintHandler', @fStdPrintHandler, bObject);
  57.     INHERITED Fields(DoToField);
  58.     END;
  59.  
  60. {--------------------------------------------------------------------------------------------------}
  61. {$S PrintActual}
  62. {$Push}
  63. {$IFC qTrace}{$D+}{$ENDC} { No tracing till we get the port straightened out since the current
  64. port could already be disposed (Thank you Direct connect ImageWriter!) }
  65.  
  66. PROCEDURE IdleProcForTStdPrintHandler;
  67.     VAR
  68.         savedPort:    GrafPtr;
  69.     
  70.     BEGIN
  71.     IF gJobPrintHandler <> NIL THEN
  72.         BEGIN
  73.         GetPort(savedPort);
  74.         SetPort(gWorkPort);                                { Nice safe port in a storm }
  75.         gJobPrintHandler.DoPrintIdling;                 { Forward to the current print job handler }
  76.         SetPort(savedPort);
  77.         END;
  78.     END;
  79. {$Pop}
  80.  
  81. {--------------------------------------------------------------------------------------------------}
  82. {$S PrintActual}
  83.  
  84. PROCEDURE TStdPrintHandler.DoPrintIdling;
  85.  
  86.     CONST
  87.         myDlgMask            = mDownMask + mUpMask + keyDownMask + keyUpMask + autoKeyMask;
  88.  
  89.     VAR
  90.         ch:                 CHAR;
  91.         keycode:            INTEGER;
  92.         aDialog:            DialogPtr;
  93.         anEvent:            EventRecord;
  94.         item:                INTEGER;
  95.         theItem:            Handle;
  96.         itemType:            INTEGER;
  97.         box:                Rect;
  98.         dontCare:            LONGINT;
  99.  
  100.     BEGIN
  101.     IF gApplication.GetEvent(myDlgMask, 0, NIL, anEvent) THEN
  102.         BEGIN
  103.   { Workaround for LaserWriter driver bug: it tries to set GhostWindow
  104.    so that its status window is invisible. Unfortunately, it doesn't
  105.    always set it, so IsDialogEvent returns FALSE (the status window
  106.    is frontmost).  If ours isn't already in front, force it there. }
  107.         IF fPrintDialog <> FrontWindow THEN
  108.             gApplication.SelectWMgrWindow(fPrintDialog);
  109.  
  110.         CASE anEvent.what OF
  111.             keyDown:
  112.                 WITH anEvent DO
  113.                     BEGIN
  114.                     ch := CHR(BAND(message, charCodeMask));
  115.                     keycode := BSR(BAND(message, keyCodeMask), 8);
  116.                     IF ((ch = '.') & (BAND(modifiers, cmdKey) <> 0)) | ((ch = chEscape) & (keycode =
  117.                        kEscapeVirtualCode)) THEN
  118.                         BEGIN
  119.                         IF gFinderPrinting THEN
  120.                             item := cancel                { Want the 'Cancel All' button }
  121.                         ELSE
  122.                             item := 1;                    { Want the 'Cancel' button }
  123.  
  124.                         { Flash the appropriate button }
  125.                         GetDItem(fPrintDialog, item, itemType, theItem, box);
  126.                         HiliteControl(ControlHandle(theItem), 10);
  127.                         Delay(8, dontCare);
  128.                         HiliteControl(ControlHandle(theItem), 0);
  129.  
  130.                         PrSetError(iPrAbort);
  131.                         gCancelAllPrinting := TRUE;
  132.                         END;
  133.                     END;
  134.             OTHERWISE
  135.                 IF IsDialogEvent(anEvent) & DialogSelect(anEvent, aDialog, item) & (aDialog =
  136.                    fPrintDialog) THEN
  137.                     CASE item OF
  138.                         1:
  139.                             PrSetError(iPrAbort);        { Cancel }
  140.  
  141.                         cancel:
  142.                             BEGIN                        { Cancel All Printing }
  143.                             PrSetError(iPrAbort);
  144.                             gCancelAllPrinting := TRUE;
  145.                             END;
  146.  
  147.                     END;
  148.         END;
  149.         END;
  150.     END;
  151.  
  152. {--------------------------------------------------------------------------------------------------}
  153. {$S PrintActual}
  154.  
  155. PROCEDURE TStdPrintHandler.ChkPrintErr(VAR err: OSErr;
  156.                                        VAR proceed: BOOLEAN;
  157.                                        VAR ranOutOfSpace: BOOLEAN);
  158.  
  159.     BEGIN
  160.     IF proceed THEN
  161.         BEGIN
  162.         err := PrError;
  163.         IF err <> noErr THEN
  164.             BEGIN
  165.             {$IFC qDebug}
  166.             IF gDebugPrinting THEN
  167.                 WriteLn('Error from PrError is ', err: 1);
  168.             {$ENDC}
  169.             proceed := FALSE;
  170.             IF err = - 1                                { iPrSavPFil } THEN
  171.                 ranOutOfSpace := TRUE;
  172.             END;
  173.         END;
  174.     END;
  175.  
  176. {--------------------------------------------------------------------------------------------------}
  177. {$S PrintRes}
  178.  
  179. PROCEDURE TStdPrintHandler.GetDriverName(VAR driverName: Str255);
  180.  
  181.     VAR
  182.         driverHandle:        StringHandle;
  183.  
  184.     BEGIN
  185.     driverHandle := GetString(kPrintDriverName);        { Get current driver }
  186.  
  187.  { Be a little cautious, in case we accidentally pick up something
  188.   which is not what we expect, or we can't find it. }
  189.     IF (driverHandle <> NIL) & (LENGTH(driverHandle^^) < 64) THEN
  190.     {$Push} {$H-}
  191.         CopyStr255(driverHandle^^, @driverName)
  192.         {$Pop}
  193.     ELSE
  194.         driverName := '';
  195.     END;
  196.  
  197. {--------------------------------------------------------------------------------------------------}
  198. {$S PrintInit}
  199. { Initialize the printing unit.  Call exactly once }
  200.  
  201. PROCEDURE InitUPrinting;
  202.  
  203.     VAR
  204.         err:                OSErr;
  205.         aStdPrintHandler:    TStdPrintHandler;
  206.  
  207.     BEGIN
  208.     gCancelAllPrinting := FALSE;
  209.     gFinderHPrint := NIL;
  210.     gJobPrintHandler := NIL;
  211.  
  212.     SetRect(gStdPageMargins, 72, 72, - 72, - 72);        { 1" margins std default }
  213.  
  214.     WITH gBreaksPenState DO
  215.         BEGIN
  216.         pnLoc := gZeroPt;
  217.         pnSize := Point($00020002);
  218.         pnMode := patCopy;
  219.         StuffHex(@pnPat, 'CC663399CC663399');
  220.         END;
  221.  
  222.     gCouldPrint := TRUE;
  223.  
  224.     gUPrintingInitialized := TRUE;
  225.  
  226.     IF gPrintHandler = gNullPrintHandler THEN
  227.         BEGIN                                            { Install a StdPrintHandler in UMacApp
  228.                                                          global variable gPrintHandler }
  229.         New(aStdPrintHandler);
  230.         FailNIL(aStdPrintHandler);
  231.         aStdPrintHandler.IStdPrintHandler(NIL, NIL, kSquareDots, kFixedSize, kFixedSize);
  232.         aStdPrintHandler.fFinderJobDialog := TRUE;
  233.         gPrintHandler := aStdPrintHandler;
  234.         END;
  235.  
  236.     END;
  237.  
  238. {--------------------------------------------------------------------------------------------------}
  239. {$S MAPrintingRes}
  240. { Synonym For InitUPrinting }
  241.  
  242. PROCEDURE InitPrinting;
  243.  
  244.     BEGIN
  245.     InitUPrinting;
  246.     END;
  247.  
  248. {--------------------------------------------------------------------------------------------------}
  249. {$S PrintSpool}
  250.  
  251. PROCEDURE TStdPrintHandler.PrintSpoolFile(anHPrint: Handle;
  252.                                           VAR err: OSErr;
  253.                                           VAR proceed: BOOLEAN);
  254.  
  255.     VAR
  256.         prStatus:            TPrStatus;
  257.         b:                    BOOLEAN;
  258.  
  259.     BEGIN
  260.     proceed := TRUE;
  261.     PRPicFile(THPrint(anHPrint), NIL, NIL, NIL, prStatus);
  262.     ChkPrintErr(err, proceed, b);
  263.     END;
  264.  
  265. {--------------------------------------------------------------------------------------------------}
  266. {$S PrintOpen}
  267.  
  268. PROCEDURE TStdPrintHandler.IStdPrintHandler(itsDocument: TDocument;
  269.                                             itsView: TView;
  270.                                             itsSquareDots, itsHFixedSize, itsVFixedSize: BOOLEAN);
  271.  
  272.     VAR
  273.         fi:                 FailInfo;
  274.  
  275.     PROCEDURE HdlInitFailed(error: OSErr;
  276.                             message: LONGINT);
  277.  
  278.         BEGIN
  279.         Free;
  280.         END;
  281.  
  282.     BEGIN
  283.     {$IFC qDebug}
  284.     IF NOT gUPrintingInitialized THEN
  285.         BEGIN
  286.         ProgramBreak('InitUPrinting must be called before creating a print handler.');
  287.         Failure(noErr, 0);
  288.         END;
  289.     {$ENDC}
  290.  
  291.     fPrintDialog := NIL;
  292.     fPPrPort := NIL;
  293.     fHPrint := NIL;
  294.     IPrintHandler(itsView);
  295.     fDocument := itsDocument;
  296.  
  297.     CatchFailures(fi, HdlInitFailed);
  298.  
  299.     fStartPage := 1;
  300.     fPageDirection := v;                                { Page 2 is below page 1, etc. }
  301.     fShowBreaks := FALSE;
  302.     fFixedSizePages[h] := itsHFixedSize;
  303.     fFixedSizePages[v] := itsVFixedSize;
  304.  
  305.     fPrinterDev := kNeverInitialized;
  306.  
  307.     fLastPrinterName := NIL;
  308.     fFinderSetup := FALSE;
  309.     fFinderJobDialog := FALSE;
  310.     {$Push} {$H-}
  311.     fSquareDots := itsSquareDots;
  312.     SetPt(fLastStrip, MAXINT, MAXINT);
  313.     fLastBreak := gZeroVPt;
  314.     {$Pop}
  315.  
  316.     fPageAreas.theMargins := gStdPageMargins;
  317.     fMarginRes.h := 72;
  318.     fMarginRes.v := 72;
  319.     fMinimalMargins := FALSE;
  320.  
  321.     fLastCheckedPrinter := 0;
  322.     IF itsView <> NIL THEN
  323.         BEGIN
  324.         { allocates a handle for the print-info, and sets my field fHPrint accordingly }
  325.         SetDefaultPrintInfo;
  326.  
  327.         IF itsDocument <> NIL THEN
  328.             BEGIN
  329.             IF itsDocument.fDocPrintHandler = NIL THEN
  330.                 itsDocument.fDocPrintHandler := SELF;
  331.             IF itsDocument.fPrintInfo = NIL THEN
  332.                 IF itsDocument.fSharePrintInfo THEN
  333.                     itsDocument.fPrintInfo := fHPrint;
  334.             END;
  335.  
  336.         fView.AttachPrintHandler(SELF);
  337.         END;
  338.  
  339.     Success(fi);
  340.     END;
  341.  
  342. {--------------------------------------------------------------------------------------------------}
  343. {$S PrintClose}
  344.  
  345. PROCEDURE TStdPrintHandler.Free; OVERRIDE;
  346.  
  347.     VAR
  348.         dontDispose:        BOOLEAN;
  349.         itsDocument:        TDocument;
  350.  
  351.     BEGIN
  352.     dontDispose := fView <> NIL;
  353.     IF dontDispose THEN
  354.         BEGIN
  355.         IF fView.fPrintHandler = SELF THEN
  356.             fView.AttachPrintHandler(gNullPrintHandler);
  357.         fView := NIL;
  358.  
  359.         itsDocument := fDocument;
  360.         dontDispose := itsDocument <> NIL;
  361.         IF dontDispose THEN
  362.             BEGIN
  363.             IF itsDocument.fDocPrintHandler = SELF THEN
  364.                 itsDocument.fDocPrintHandler := NIL;
  365.             dontDispose := itsDocument.fSharePrintInfo;
  366.             END;
  367.         IF dontDispose THEN
  368.             dontDispose := itsDocument.fPrintInfo = fHPrint;
  369.         fDocument := NIL;
  370.  
  371.         END;
  372.     IF NOT dontDispose THEN
  373.         fHPrint := DisposeIfHandle(fHPrint);
  374.     fHPrint := NIL;                                     { Always drop my reference }
  375.  
  376.     Handle(fLastPrinterName) := DisposeIfHandle(fLastPrinterName);
  377.  
  378.     BanishPrintDialog;
  379.  
  380.     IF gJobPrintHandler = SELF THEN                     { let's be safe }
  381.         gJobPrintHandler := NIL;
  382.  
  383.     INHERITED Free;
  384.     END;
  385.  
  386. {--------------------------------------------------------------------------------------------------}
  387. {$S PrintImage}
  388.  
  389. PROCEDURE TStdPrintHandler.AdornPage;
  390. {$IFC qDebug}
  391.  
  392.     CONST
  393.         botSlop             = 8;                        { ??? Arbitrary choice }
  394.  
  395.     VAR
  396.         heading:            Str255;
  397.         pgStr:                Str255;
  398.         handyRect:            Rect;
  399.         xLoc:                INTEGER;
  400.         itsWidth:            INTEGER;
  401.         rPlusL:             INTEGER;
  402.         itsBottom:            INTEGER;
  403.         theFontInfo:        FontInfo;
  404.         theTextRect:        Rect;
  405.         {$ENDC}
  406.  
  407.     BEGIN
  408.     {$IFC qDebug}
  409.     IF gDebugPrinting THEN                                { Print extra stuff if debugging }
  410.         BEGIN
  411.         NumToString(fFocusedPage, pgStr);
  412.         TextFont(applFont);
  413.         TextFace([]);
  414.         TextSize(12);
  415.         heading := CONCAT('-', pgStr, '-');             { ??? Make easier for client to change this
  416.                                                          }
  417.  
  418.         { • draw the heading }
  419.         itsWidth := StringWidth(heading);
  420.         WITH fPageAreas.thePaper DO
  421.             rPlusL := right + left;
  422.         itsBottom := fPageAreas.theInk.bottom - botSlop;
  423.         GetFontInfo(theFontInfo);
  424.         {$Push} {$H-}
  425.         WITH theTextRect, theFontInfo DO
  426.             BEGIN
  427.             left := (rPlusL - itsWidth) DIV 2;
  428.             top := itsBottom - ascent;
  429.             right := left + itsWidth;
  430.             bottom := itsBottom + descent;
  431.             END;
  432.         {$Pop}
  433.         MADrawString(@heading, theTextRect, teJustSystem);
  434.  
  435.         { Additionally frame the printable area of the page if gDebugPrinting }
  436.         handyRect := fPageAreas.theInk;
  437.         PenSize(1, 1);
  438.         FrameRect(handyRect);
  439.  
  440.         { Frame the 'interior' of the page }
  441.         PenSize(2, 2);
  442.         handyRect := fPageAreas.theInterior;
  443.         FrameRect(handyRect);
  444.         END;
  445.     {$ENDC}
  446.     END;
  447.  
  448. {--------------------------------------------------------------------------------------------------}
  449. {$S PrintActual}
  450.  
  451. PROCEDURE TStdPrintHandler.BanishPrintDialog;
  452.  
  453.     BEGIN
  454.     IF fPrintDialog <> NIL THEN
  455.         BEGIN
  456.         IF fPrintDialog = thePort THEN                    { Only need to invalidate focus if freed
  457.                                                          dialog is the current port }
  458.             BEGIN
  459.             gApplication.InvalidateFocus;
  460.             SetPort(gWorkPort);
  461.             END;
  462.         DisposDialog(fPrintDialog);
  463.         fPrintDialog := NIL;
  464.         END;
  465.     END;
  466.  
  467. {--------------------------------------------------------------------------------------------------}
  468. {$S PrintRes}
  469.  
  470. FUNCTION TStdPrintHandler.BreakFollowing(vhs: VHSelect;
  471.                                          prevBreak: VCoordinate;
  472.                                          VAR automatic: BOOLEAN): VCoordinate; OVERRIDE;
  473. { Called from fView.DoBreakFollowing, }
  474.  
  475.     VAR
  476.         orthoVHS:            VHSelect;
  477.         newLoc:             VCoordinate;
  478.  
  479.     BEGIN
  480.     orthoVHS := gOrthogonal[vhs];
  481.     automatic := TRUE;
  482.     newLoc := Min(prevBreak + fViewPerPage.vh[orthoVHS], fPrintExtent.botRight.vh[orthoVHS]);
  483.  
  484.     {$IFC qDebug}
  485.     IF newLoc <= prevBreak THEN
  486.         BEGIN
  487.         WriteLn('No advance in BreakFollowing; vhs = ', ORD(vhs): 1, ' prevBreak = ', prevBreak: 1,
  488.                 ' newLoc = ', newLoc: 1, ' view size: ', fPrintExtent.botRight.vh[orthoVHS]: 1);
  489.         ProgramBreak('No advance in BreakFollowing');
  490.         END;
  491.     {$ENDC}
  492.  
  493.     BreakFollowing := newLoc;
  494.     END;
  495.  
  496. {--------------------------------------------------------------------------------------------------}
  497. {$S PrintNonRes}
  498.  
  499. PROCEDURE TStdPrintHandler.CalcPageStrips(VAR pageStrips: Point); OVERRIDE;
  500.  
  501.     VAR
  502.         vhs, ortho:         VHSelect;
  503.         nStrips:            INTEGER;
  504.  
  505.     FUNCTION FindLimit(loc: VCoordinate;
  506.                        automatic: BOOLEAN): BOOLEAN;
  507.  
  508.         BEGIN
  509.         nStrips := nStrips + 1;
  510.         FindLimit := FALSE;
  511.         END;
  512.  
  513.     BEGIN
  514.  
  515.  { If pages are of fixed size, then simple divide the total size by the
  516.   page size.  Otherwise, count up the page breaks one by one. }
  517.  
  518.     FOR vhs := v TO h DO
  519.         BEGIN
  520.         ortho := gOrthogonal[vhs];
  521.         IF fFixedSizePages[ortho] THEN
  522.         {$Push} {$H-}
  523.             WITH fPrintExtent, fViewPerPage DO
  524.                 pageStrips.vh[vhs] := (botRight.vh[ortho] - topLeft.vh[ortho] + vh[ortho] - 1) DIV
  525.                                       vh[ortho]
  526.                 {$Pop}
  527.         ELSE
  528.             BEGIN
  529.             nStrips := 0;
  530.             EachBreak(vhs, TRUE, FindLimit);
  531.             pageStrips.vh[vhs] := nStrips;
  532.             END;
  533.         END;
  534.     END;
  535.  
  536. {--------------------------------------------------------------------------------------------------}
  537. {$S PrintNonRes}
  538.  
  539. PROCEDURE TStdPrintHandler.CalcViewPerPage(VAR amtPerPage: VPoint); OVERRIDE;
  540.  
  541.     VAR
  542.         vhs:                VHSelect;
  543.  
  544.     BEGIN
  545.     WITH fPageAreas DO
  546.     {$Push} {$H-}
  547.         FOR vhs := v TO h DO
  548.             amtPerPage.vh[vhs] := MAX(1, ((ORD4(thePaper.botRight.vh[vhs] - thePaper.topLeft.vh[vhs]
  549.                                                 - ABS(theMargins.topLeft.vh[vhs]) -
  550.                                                 ABS(theMargins.botRight.vh[vhs])))));
  551.     {$Pop}
  552.     END;
  553.  
  554. {--------------------------------------------------------------------------------------------------}
  555. {$S PrintRes}
  556.  
  557. PROCEDURE TStdPrintHandler.CheckPrinter; OVERRIDE;
  558.  
  559.     VAR
  560.         oldPageAreas:        PageAreas;
  561.         oldPrinterDev:        INTEGER;
  562.         oldDevRes:            Point;
  563.         oldMarginRes:        Point;
  564.         didChange:            BOOLEAN;
  565.         msgSent:            BOOLEAN;
  566.         driverName:         Str255;
  567.         aRect, bRect:        Rect;
  568.  
  569.     PROCEDURE ItChanged(aView: TView);                    { this msg is sent to all views if my
  570.                                                          associated document is the kind where one
  571.                                                          copy of the PrintInfo is shared among all
  572.                                                          views }
  573.  
  574.         BEGIN
  575.         aView.DoPrinterChanged;
  576.         END;
  577.  
  578.     BEGIN
  579.     oldPageAreas := fPageAreas;
  580.     oldPrinterDev := fPrinterDev;
  581.     oldDevRes := fDeviceRes;
  582.     oldMarginRes := fMarginRes;
  583.  
  584.  { It costs an open and several LoadResources to call PrValidate.  Before
  585.   doing so, check to see if the printer has actually changed. }
  586.     IF fLastCheckedPrinter < gLastDeskAcc THEN            { If we haven't checked printer since the }
  587.         BEGIN                                            { last time the Chooser might have run… }
  588.         GetDriverName(driverName);
  589.         {$Push} {$H-}                                    { EqualString does NOT move memory }
  590.         IF (fLastPrinterName = NIL) | (NOT EqualString(fLastPrinterName^^, driverName, FALSE,
  591.            TRUE)) THEN
  592.         {$Pop}
  593.             BEGIN                                        { Printer name has changed… }
  594.             Handle(fLastPrinterName) := DisposeIfHandle(fLastPrinterName); { out with the old }
  595.             fLastPrinterName := NewString(driverName);    { in with the new }
  596.             FailNIL(fLastPrinterName);
  597.             ValidatePrintRecord(didChange);             { …and validate the print record. }
  598.             END;
  599.         fLastCheckedPrinter := TickCount;
  600.         END;
  601.  
  602.     WITH THPrint(fHPrint)^^ DO
  603.     {$Push} {$H-}
  604.         BEGIN
  605.         fPageAreas.thePaper := rPaper;
  606.  
  607.         {$IFC FALSE}
  608.         { This *old* computation for fMarginRes doesn't work with the current printer drivers,
  609.           so use prInfo's iHRes & iVRes. It's conceivable that this computation was correct
  610.           for some *older* versions of the printer drivers. But what versions???
  611.           NOTE: the Print Shop recommends always using the latest version of the print drivers,
  612.           even with older systems. }
  613.         WITH fPageAreas.thePaper, fMarginRes DO         { Recompute effective device resolution }
  614.             BEGIN
  615.             h := (IntMultiply(iPrPgFract, right - left)) DIV prStl.iPageH;
  616.             v := (IntMultiply(iPrPgFract, bottom - top)) DIV prStl.iPageV;
  617.             END;
  618.         {$ENDC}
  619.  
  620.         WITH prInfo, fMarginRes DO                        { Store latest data from MacPrint prInfo
  621.                                                          record into my own instance variables }
  622.             BEGIN
  623.             h := iHRes;                                 { read the new device resolution values }
  624.             v := iVRes;
  625.  
  626.             fPrinterDev := iDev;
  627.             SetPt(fDeviceRes, iHRes, iVRes);
  628.             WITH fPageAreas DO
  629.                 BEGIN
  630.                 theInk := rPage;
  631.                 IF NOT fMinimalMargins THEN
  632.                     SetRect(theMargins, IntMultiply(theMargins.left, h) DIV oldMarginRes.h,
  633.                             IntMultiply(theMargins.top, v) DIV oldMarginRes.v,
  634.                             IntMultiply(theMargins.right, h) DIV oldMarginRes.h,
  635.                             IntMultiply(theMargins.bottom, v) DIV oldMarginRes.v);
  636.                 END;
  637.             END;
  638.         {$Pop}
  639.         END;
  640.  
  641.     aRect := fPageAreas.thePaper;
  642.     bRect := fPageAreas.theInk;
  643.     IF (NOT EqualRect(aRect, oldPageAreas.thePaper)) | (NOT EqualRect(bRect, oldPageAreas.theInk)) |
  644.        (NOT EqualPt(fDeviceRes, oldDevRes)) | (oldPrinterDev = kNeverInitialized) THEN
  645.         BEGIN                                            { something important to our projection
  646.                                                          model changed... }
  647.         msgSent := FALSE;
  648.         IF fDocument <> NIL THEN
  649.             IF fDocument.fSharePrintInfo THEN
  650.                 BEGIN
  651.                 fDocument.ForAllViewsDo(ItChanged);
  652.                 msgSent := TRUE;
  653.                 END;
  654.  
  655.         IF NOT msgSent THEN                             { didn't send msg to all views, current
  656.                                                          company included, so now we need to tell
  657.                                                          must my local view }
  658.             fView.DoPrinterChanged;
  659.         END;
  660.     END;
  661.  
  662. {--------------------------------------------------------------------------------------------------}
  663. {$S PrintImage}
  664.  
  665. PROCEDURE TStdPrintHandler.ChooseSpoolFile(VAR spoolFileName: Str255;
  666.                                            VAR spoolVRefNum: INTEGER;
  667.                                            VAR pagesPerSubjob: INTEGER);
  668.  
  669.     BEGIN
  670.     spoolFileName := '';                                { Default choices tell MacPrint to use its
  671.                                                          standard choice algorithm }
  672.     spoolVRefNum := 0;
  673.  { Print Shop suggests attempting to print entire document.  If it
  674.   runs out of space, then PerformPrinting will retry with a
  675.   smaller number of pages. }
  676.     pagesPerSubjob := MAXINT;
  677.     END;
  678.  
  679. {--------------------------------------------------------------------------------------------------}
  680. {$S PrintRes}
  681.  
  682. PROCEDURE TStdPrintHandler.ClosePrintShop;
  683.  
  684.     VAR
  685.         err:                OSErr;
  686.  
  687.     BEGIN
  688.     PrClose;
  689.     {$IFC qDebug}
  690.     err := PrError;                                     { Now check for fresh error from MacPrint --
  691.                                                          only for debugging, since ChkPrintErr
  692.                                                          checks afresh in the real world }
  693.     IF err <> noErr THEN
  694.         WriteLn('Error from MacPrint is: ', err: 1);
  695.     {$ENDC}
  696.     END;
  697.  
  698. {--------------------------------------------------------------------------------------------------}
  699. {$S PrintRes}
  700.  
  701. PROCEDURE TStdPrintHandler.DoInMacPrint(PROCEDURE WhatToDo);
  702.  
  703.     VAR
  704.         fi:                 FailInfo;
  705.  
  706.     PROCEDURE HdlPrintFailure(error: OSErr;
  707.                               message: LONGINT);
  708.  
  709.         BEGIN
  710.         ClosePrintShop;
  711.         SetPort(gWorkPort);                                { Might be left looking at a dead port }
  712.         gApplication.InvalidateFocus;
  713.         END;
  714.  
  715.     BEGIN
  716.     IF gCouldPrint THEN
  717.         BEGIN
  718.         PrSetError(noErr);                                { Clear printer-error flag }
  719.         CatchFailures(fi, HdlPrintFailure);
  720.         OpenPrintShop;
  721.         WhatToDo;                                        { Do what needs to be done }
  722.         Success(fi);
  723.         ClosePrintShop;
  724.         SetPort(gWorkPort);                                { Might be left looking at a dead port }
  725.         gApplication.InvalidateFocus;
  726.         END;
  727.     { NB: if gCouldPrint is FALSE, DoInMacPrint is a no-op }
  728.     END;
  729.  
  730. {--------------------------------------------------------------------------------------------------}
  731. {$S PrintSelCommand}
  732.  
  733. FUNCTION TStdPrintHandler.DoMenuCommand(aCmdNumber: CmdNumber): TCommand; OVERRIDE;
  734.  
  735.     VAR
  736.         proceed:            BOOLEAN;
  737.  
  738.     FUNCTION LaunchPrintCommand(aCmdNumber: CmdNumber): TCommand;
  739.  
  740.         VAR
  741.             aPrintCommand:        TPrintCommand;
  742.  
  743.         BEGIN
  744.         New(aPrintCommand);
  745.         FailNIL(aPrintCommand);
  746.         aPrintCommand.IPrintCommand(aCmdNumber, SELF);
  747.         LaunchPrintCommand := aPrintCommand;
  748.         END;
  749.  
  750.     BEGIN
  751.     DoMenuCommand := NIL;
  752.     CASE aCmdNumber OF
  753.  
  754.         cPrint:
  755.             BEGIN
  756.             CheckPrinter;
  757.             IF PoseJobDialog THEN
  758.                 DoMenuCommand := LaunchPrintCommand(aCmdNumber);
  759.             END;
  760.         cPrintOne:
  761.             BEGIN
  762.             CheckPrinter;
  763.             IF SetupPrintOne THEN
  764.                 DoMenuCommand := LaunchPrintCommand(aCmdNumber);
  765.             END;
  766.         cPageSetup:
  767.             DoMenuCommand := PosePageSetupDialog(proceed, TRUE);
  768.  
  769.         cShowBreaks:                                    { Toggle state of "Show Breaks" }
  770.             BEGIN
  771.             fShowBreaks := NOT fShowBreaks;
  772.             InvalPageFeedback;                            { force redraw of area the breaks did or
  773.                                                          will occupy }
  774.             END;
  775.  
  776.         OTHERWISE
  777.             DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  778.     END;
  779.     END;
  780.  
  781. {--------------------------------------------------------------------------------------------------}
  782. {$S PrintRes}
  783.  
  784. PROCEDURE TStdPrintHandler.DoSetupMenus; OVERRIDE;
  785.  
  786.     BEGIN
  787.     INHERITED DoSetupMenus;
  788.  
  789.     IF gCouldPrint & (fView <> NIL) & (NOT MemSpaceIsLow) THEN
  790.         BEGIN
  791.         Enable(cPrint, TRUE);
  792.         Enable(cPageSetup, TRUE);
  793.         Enable(cPrintOne, TRUE);
  794.         END;
  795.  
  796.     EnableCheck(cShowBreaks, TRUE, fShowBreaks);
  797.     END;
  798.  
  799. {--------------------------------------------------------------------------------------------------}
  800. {$S PrintRes}
  801.  
  802. PROCEDURE TStdPrintHandler.DrawPrintFeedback(area: Rect); OVERRIDE;
  803. { Draws page breaks and page numbers }
  804.  
  805.     VAR
  806.         vhs:                VHSelect;
  807.         orthoVHS:            VHSelect;
  808.         whichBreak:         INTEGER;
  809.         viewArea:            VRect;
  810.         {$IFC qDebug}
  811.         pageNumStyle:        TextStyle;
  812.         {$ENDC}
  813.  
  814. {--------------------------------------------------------------------------------------------------}
  815.  
  816.     FUNCTION DrawABreak(loc: VCoordinate;
  817.                         automatic: BOOLEAN): BOOLEAN;
  818.  
  819.         BEGIN
  820.         IF loc > viewArea.botRight.vh[orthoVHS] THEN
  821.             DrawABreak := TRUE
  822.         ELSE
  823.             BEGIN
  824.             DrawABreak := FALSE;
  825.             whichBreak := whichBreak + 1;
  826.             IF (loc > viewArea.topLeft.vh[orthoVHS] - gBreaksPenState.pnSize.vh[orthoVHS]) THEN
  827.                 fView.DoDrawPageBreak(vhs, whichBreak, loc, automatic);
  828.             END;
  829.         END;
  830.  
  831.     BEGIN
  832.     IF qDebug THEN
  833.         fView.AssumeFocused;
  834.     IF fShowBreaks | gDebugPrinting THEN
  835.         BEGIN
  836.         SetPrintExtent;                                 { Make sure print extent is accurate before
  837.                                                          starting }
  838.  
  839.         {$IFC qDebug}
  840.         IF gDebugPrinting THEN                            { Now draw Page numbers in the corners of
  841.                                                          pages, if desired }
  842.             BEGIN
  843.             SetTextStyle(pageNumStyle, applFont, [bold], 9, gRGBBlack);
  844.             SetPortTextStyle(pageNumStyle);
  845.             END;
  846.         {$ENDC}
  847.  
  848.         SetPenState(gBreaksPenState);
  849.         fView.QDToViewRect(area, viewArea);
  850.  
  851.         FOR vhs := v TO h DO
  852.             BEGIN
  853.             orthoVHS := gOrthogonal[vhs];
  854.             whichBreak := 0;
  855.             EachBreak(vhs, FALSE, DrawABreak);
  856.             END;
  857.         END;
  858.     END;
  859.  
  860. {--------------------------------------------------------------------------------------------------}
  861. {$S PrintRes}
  862.  
  863. PROCEDURE TStdPrintHandler.DrawPageBreak(vhs: VHSelect;
  864.                                          whichBreak: INTEGER;
  865.                                          loc: VCoordinate;
  866.                                          automatic: BOOLEAN); OVERRIDE;
  867.  
  868.     VAR
  869.         vPt:                VPoint;
  870.         qdStartPt:            Point;
  871.         qdEndPt:            Point;
  872.         {$IFC qDebug}
  873.         i:                    INTEGER;
  874.         hLoc:                VCoordinate;
  875.         aString:            Str255;
  876.         theFontInfo:        FontInfo;
  877.         theTextRect:        Rect;
  878.         {$ENDC}
  879.  
  880.     BEGIN
  881.     vPt.vh[gOrthogonal[vhs]] := loc;
  882.     vPt.vh[vhs] := 0;
  883.     qdStartPt := fView.ViewToQDPt(vPt);
  884.     vPt.vh[vhs] := fView.fSize.vh[vhs] - gBreaksPenState.pnSize.vh[vhs];
  885.     qdEndPt := fView.ViewToQDPt(vPt);
  886.  
  887.     IF fShowBreaks THEN
  888.         BEGIN
  889.         MoveTo(qdStartPt.h, qdStartPt.v);
  890.         LineTo(qdEndPt.h, qdEndPt.v);
  891.         END;
  892.  
  893.     {$IFC qDebug}
  894.     IF gDebugPrinting THEN
  895.         IF vhs = h THEN
  896.             FOR i := 0 TO fPageStrips.v DO
  897.                 BEGIN
  898.                 IF i = 0 THEN
  899.                     hLoc := 0
  900.                 ELSE
  901.                     GetBreakCoord(v, i, hLoc);
  902.  
  903.                 GetFontInfo(theFontInfo);
  904.  
  905.                 NumToString(StripToPage(whichBreak - 1, i), aString);
  906.                 WITH theFontInfo, qdStartPt DO
  907.                     SetRect(theTextRect, hLoc + 3, v - 3 - ascent, { top computed based on the
  908.                                                                     bottom - text height }
  909.                             hLoc + 3 + StringWidth(aString), v - 3 + descent);
  910.                 MADrawString(@aString, theTextRect, teJustSystem);
  911.  
  912.                 NumToString(StripToPage(whichBreak, i), aString);
  913.                 WITH theFontInfo, qdEndPt DO
  914.                     SetRect(theTextRect, hLoc + 3, v + 10 - ascent, { top computed based on the
  915.                                                                      bottom - text height }
  916.                             hLoc + 3 + StringWidth(aString), v + 10 + descent);
  917.                 MADrawString(@aString, theTextRect, teJustSystem);
  918.  
  919.                 NumToString(StripToPage(whichBreak - 1, i - 1), aString);
  920.                 WITH theFontInfo, qdStartPt DO
  921.                     SetRect(theTextRect, hLoc - StringWidth(aString) - 3, v - 3 - ascent, { top
  922.                                 computed based on the bottom - text height }
  923.                             hLoc - 3, v - 3 + descent);
  924.                 MADrawString(@aString, theTextRect, teJustSystem);
  925.  
  926.                 NumToString(StripToPage(whichBreak, i - 1), aString);
  927.                 WITH theFontInfo, qdEndPt DO
  928.                     SetRect(theTextRect, hLoc - StringWidth(aString) - 3, v + 10 - ascent, { top
  929.                                 computed based on the bottom - text height }
  930.                             hLoc - 3, v + 10 + descent);
  931.                 MADrawString(@aString, theTextRect, teJustSystem);
  932.                 END;
  933.     {$ENDC}
  934.     END;
  935.  
  936. {--------------------------------------------------------------------------------------------------}
  937. {$S PrintImage}
  938.  
  939. PROCEDURE TStdPrintHandler.DrawPageInterior;
  940.  
  941.     BEGIN
  942.     fView.DrawContents;                                 { i.e., by default, the same code used for
  943.                                                          drawing on the screen }
  944.     END;
  945.  
  946. {--------------------------------------------------------------------------------------------------}
  947. {$S PrintRes}
  948.  
  949. PROCEDURE TStdPrintHandler.EachBreak(vhs: VHSelect;
  950.                                      includeLast: BOOLEAN;
  951.                                      FUNCTION DoToBreak(loc: VCoordinate;
  952.                                                         automatic: BOOLEAN): BOOLEAN);
  953.  
  954.     VAR
  955.         startLoc:            VCoordinate;
  956.         endLoc:             VCoordinate;
  957.         loc:                VCoordinate;
  958.         automatic:            BOOLEAN;
  959.         done:                BOOLEAN;
  960.         prevBreak:            VCoordinate;
  961.  
  962.     BEGIN
  963.     WITH fPrintExtent DO
  964.         BEGIN
  965.         startLoc := topLeft.vh[gOrthogonal[vhs]];
  966.         endLoc := botRight.vh[gOrthogonal[vhs]];
  967.         END;
  968.  
  969.     loc := startLoc;
  970.     automatic := TRUE;
  971.     done := FALSE;
  972.     WHILE (loc < endLoc) & NOT done DO
  973.         BEGIN
  974.         IF loc <> startLoc THEN
  975.             done := DoToBreak(loc, automatic);
  976.         IF qDebug THEN
  977.             prevBreak := loc;
  978.  
  979.         loc := fView.DoBreakFollowing(vhs, loc, automatic);
  980.  
  981.         IF qDebug & (loc <= prevBreak) THEN
  982.             ProgramBreak('thisBreak (loc) <= prevBreak'); { Thanks much to Larry T. ! }
  983.         END;
  984.  
  985.     IF includeLast THEN
  986.         done := DoToBreak(loc, automatic);
  987.     END;
  988.  
  989. {--------------------------------------------------------------------------------------------------}
  990. {$S PrintFields}
  991.  
  992. PROCEDURE TStdPrintHandler.Fields(PROCEDURE DoToField(fieldName: Str255;
  993.                                                       fieldAddr: Ptr;
  994.                                                       fieldType: INTEGER));
  995.  
  996.     BEGIN
  997.     DoToField('TStdPrintHandler', NIL, bClass);
  998.     DoToField('fPageAreas', NIL, bTitle);
  999.     DoToField('  thePaper', @fPageAreas.thePaper, bRect);
  1000.     DoToField('  theInk', @fPageAreas.theInk, bRect);
  1001.     DoToField('  theMargins', @fPageAreas.theMargins, bRect);
  1002.     DoToField('  theInterior', @fPageAreas.theInterior, bRect);
  1003.     DoToField('fPrintExtent', @fPrintExtent, bVRect);
  1004.     DoToField('fFixedSizePages[h]', @fFixedSizePages[h], bBoolean);
  1005.     DoToField('fFixedSizePages[v]', @fFixedSizePages[v], bBoolean);
  1006.     DoToField('fHPrint', @fHPrint, bHandle);
  1007.     DoToField('fPageStrips', @fPageStrips, bPoint);
  1008.     DoToField('fStartPage', @fStartPage, bInteger);
  1009.     DoToField('fPrinterDev', @fPrinterDev, bInteger);
  1010.     DoToField('fLastCheckedPrinter', @fLastCheckedPrinter, bLongInt);
  1011.     DoToField('fLastPrinterName', @fLastPrinterName, bStringHandle);
  1012.     DoToField('fPageDirection', @fPageDirection, bVHSelect);
  1013.     DoToField('fShowBreaks', @fShowBreaks, bBoolean);
  1014.     DoToField('fFinderSetup', @fFinderSetup, bBoolean);
  1015.     DoToField('fFinderJobDialog', @fFinderJobDialog, bBoolean);
  1016.     DoToField('fSquareDots', @fSquareDots, bBoolean);
  1017.     DoToField('fMinimalMargins', @fMinimalMargins, bBoolean);
  1018.     DoToField('fLastStrip', @fLastStrip, bPoint);
  1019.     DoToField('fLastBreak', @fLastBreak, bVPoint);
  1020.     DoToField('fViewedRect', @fViewedRect, bVRect);
  1021.     DoToField('fMarginRes', @fMarginRes, bPoint);
  1022.     DoToField('fPrintDialog', @fPrintDialog, bWindowPtr); { need a bDialogPtr }
  1023.  
  1024.     DoToField('fPPrPort', NIL, bTitle);
  1025.     IF fPPrPort <> NIL THEN
  1026.         BEGIN
  1027.         DoToField('  gPort', @fPPrPort, bGrafPtr);
  1028.         DoToField('  gProcs', NIL, bTitle);
  1029.         DoToField('    textProc', @fPPrPort^.gProcs.textProc, bPointer);
  1030.         DoToField('    lineProc', @fPPrPort^.gProcs.lineProc, bPointer);
  1031.         DoToField('    rectProc', @fPPrPort^.gProcs.rectProc, bPointer);
  1032.         DoToField('    rRectProc', @fPPrPort^.gProcs.rRectProc, bPointer);
  1033.         DoToField('    ovalProc', @fPPrPort^.gProcs.ovalProc, bPointer);
  1034.         DoToField('    arcProc', @fPPrPort^.gProcs.arcProc, bPointer);
  1035.         DoToField('    polyProc', @fPPrPort^.gProcs.polyProc, bPointer);
  1036.         DoToField('    rgnProc', @fPPrPort^.gProcs.rgnProc, bPointer);
  1037.         DoToField('    bitsProc', @fPPrPort^.gProcs.bitsProc, bPointer);
  1038.         DoToField('    commentProc', @fPPrPort^.gProcs.commentProc, bPointer);
  1039.         DoToField('    txMeasProc', @fPPrPort^.gProcs.txMeasProc, bPointer);
  1040.         DoToField('    getPicProc', @fPPrPort^.gProcs.getPicProc, bPointer);
  1041.         DoToField('    putPicProc', @fPPrPort^.gProcs.putPicProc, bPointer);
  1042.         DoToField('  IGParam1', @fPPrPort^.lGParam1, bLongInt);
  1043.         DoToField('  IGParam2', @fPPrPort^.lGParam2, bLongInt);
  1044.         DoToField('  IGParam3', @fPPrPort^.lGParam3, bLongInt);
  1045.         DoToField('  IGParam4', @fPPrPort^.lGParam4, bLongInt);
  1046.         DoToField('  fOurPtr', @fPPrPort^.fOurPtr, bBoolean);
  1047.         DoToField('  fOurBits', @fPPrPort^.fOurBits, bBoolean);
  1048.         END;
  1049.     INHERITED Fields(DoToField);
  1050.     END;
  1051.  
  1052. {--------------------------------------------------------------------------------------------------}
  1053. {$S PrintImage}
  1054.  
  1055. PROCEDURE TStdPrintHandler.FocusOnBorder;
  1056.  
  1057.     VAR
  1058.         rectToClipTo:        Rect;
  1059.  
  1060.     BEGIN
  1061.     rectToClipTo := fPageAreas.theInk;
  1062.     WITH fPageAreas.theInk DO
  1063.     {$Push} {$H-}
  1064.         SetOrigin(left, top);                            { Only works for newer LaserWriter drivers }
  1065.     {$Pop}
  1066.     ClipRect(rectToClipTo);
  1067.     END;
  1068.  
  1069. {--------------------------------------------------------------------------------------------------}
  1070. {$S PrintImage}
  1071.  
  1072. PROCEDURE TStdPrintHandler.FocusOnInterior; OVERRIDE;
  1073.  
  1074.     VAR
  1075.         rectToClip:         Rect;
  1076.         aRect:                Rect;
  1077.         theOrigin:            Point;
  1078.         vhs:                VHSelect;
  1079.         aVRect:             VRect;
  1080.  
  1081.     BEGIN
  1082.     {$Push} {$H-}
  1083.     WITH fPageAreas DO
  1084.         BEGIN
  1085.         aRect := theInk;
  1086.         theOrigin := theInk.topLeft;
  1087.         FOR vhs := v TO h DO
  1088.             IF fView.fSize.vh[vhs] > kMaxCoord THEN
  1089.                 gLongOffset.vh[vhs] := gPageOffset.vh[vhs]
  1090.             ELSE
  1091.                 BEGIN
  1092.                 gLongOffset.vh[vhs] := 0;
  1093.                 theOrigin.vh[vhs] := theOrigin.vh[vhs] + gPageOffset.vh[vhs];
  1094.                 aRect.topLeft.vh[vhs] := aRect.topLeft.vh[vhs] + gPageOffset.vh[vhs];
  1095.                 aRect.botRight.vh[vhs] := aRect.botRight.vh[vhs] + gPageOffset.vh[vhs];
  1096.                 END;
  1097.         END;
  1098.     {$Pop}
  1099.     SetOrigin(theOrigin.h, theOrigin.v);
  1100.  
  1101.  { Clip the page to the intersection of the visible part of the view and the
  1102.   printable area of the page.  Note that in some cases (e.g., a WYSIWYG
  1103.   word processor which showed the complete page margin) parts of
  1104.   the interior might lie outside theInk.  We must clip to theInk to
  1105.   avoid slowing down PostScript printers. }
  1106.     aVRect := fViewedRect;
  1107.     fView.ViewToQDRect(aVRect, rectToClip);
  1108.     IF SectRect(rectToClip, aRect, rectToClip) THEN;
  1109.     ClipRect(rectToClip);
  1110.  
  1111.     END;
  1112.  
  1113. {--------------------------------------------------------------------------------------------------}
  1114. {$S PrintRes}
  1115.  
  1116. PROCEDURE TStdPrintHandler.GetBreakCoord(vhs: VHSelect;
  1117.                                          whichBreak: INTEGER;
  1118.                                          VAR loc: VCoordinate);
  1119.  
  1120.     VAR
  1121.         automatic:            BOOLEAN;
  1122.         i:                    INTEGER;
  1123.         startBreak:         INTEGER;
  1124.         orthoVHS:            VHSelect;
  1125.         prevBreak:            VCoordinate;
  1126.  
  1127.     BEGIN
  1128.     orthoVHS := gOrthogonal[vhs];
  1129.     IF fFixedSizePages[orthoVHS] THEN
  1130.         loc := fPrintExtent.topLeft.vh[orthoVHS] + fViewPerPage.vh[orthoVHS] * whichBreak
  1131.     ELSE IF whichBreak = fLastStrip.vh[vhs] THEN
  1132.         loc := fLastBreak.vh[vhs]
  1133.     ELSE
  1134.         BEGIN
  1135.         IF whichBreak > fLastStrip.vh[vhs] THEN
  1136.             BEGIN
  1137.             startBreak := fLastStrip.vh[vhs] + 1;
  1138.             loc := fLastBreak.vh[vhs];
  1139.             END
  1140.         ELSE
  1141.             BEGIN
  1142.             startBreak := 1;
  1143.             loc := fPrintExtent.topLeft.vh[gOrthogonal[vhs]];
  1144.             END;
  1145.         FOR i := startBreak TO whichBreak DO
  1146.             BEGIN
  1147.             IF qDebug THEN
  1148.                 prevBreak := loc;
  1149.  
  1150.             loc := fView.DoBreakFollowing(vhs, loc, automatic); { ??? error handling??? }
  1151.  
  1152.             IF qDebug & (loc <= prevBreak) THEN
  1153.                 ProgramBreak('thisBreak (loc) <= prevBreak');
  1154.             END;
  1155.         END;
  1156.     loc := Min(loc, fPrintExtent.botRight.vh[orthoVHS]);
  1157.  
  1158.     fLastStrip.vh[vhs] := whichBreak;
  1159.     fLastBreak.vh[vhs] := loc;
  1160.     END;
  1161.  
  1162. {--------------------------------------------------------------------------------------------------}
  1163. {$S PrintActual}
  1164.  
  1165. PROCEDURE TStdPrintHandler.GetDocName(VAR docName: Str255);
  1166.  
  1167.     VAR
  1168.         aWindow:            TWindow;
  1169.  
  1170.     BEGIN
  1171.     IF fDocument <> NIL THEN
  1172.         docName := fDocument.fTitle^^
  1173.     ELSE
  1174.         docName := '';
  1175.     IF docName = '' THEN
  1176.         BEGIN
  1177.         aWindow := fView.GetWindow;
  1178.         IF aWindow <> NIL THEN
  1179.             aWindow.GetTitle(docName);
  1180.         END;
  1181.     {$IFC qDebug}
  1182.     IF docName = '' THEN
  1183.         ProgramBreak('GetDocName can''t get a document or window name');
  1184.     {$ENDC}
  1185.     END;
  1186.  
  1187. {--------------------------------------------------------------------------------------------------}
  1188. {$S PrintDebug}
  1189.  
  1190. PROCEDURE TStdPrintHandler.IdentifySoftware;
  1191.  
  1192.     BEGIN
  1193.     WRITELN('UPrinting of 14 Feb 90 (Valentine''s Day), Compiled on ', COMPDATE, ' @ ', COMPTIME);
  1194.  
  1195.     INHERITED IdentifySoftware;
  1196.     END;
  1197.  
  1198. {--------------------------------------------------------------------------------------------------}
  1199. {$S PrintNonRes}
  1200.  
  1201. PROCEDURE TStdPrintHandler.InstallMargins(newMargins: Rect;
  1202.                                           areMinimalMargins: BOOLEAN);
  1203.  
  1204.     BEGIN
  1205.     fMinimalMargins := areMinimalMargins;
  1206.  
  1207.     IF fMinimalMargins THEN
  1208.         BEGIN
  1209.         WITH fPageAreas DO
  1210.             BEGIN
  1211.             {$Push} {$H-}
  1212.             theMargins := theInk;
  1213.             SubPt(thePaper.topLeft, theMargins.topLeft);
  1214.             SubPt(thePaper.botRight, theMargins.botRight);
  1215.             {$Pop}
  1216.             END;
  1217.         WITH fPageAreas DO
  1218.             theInterior := theInk;
  1219.         END
  1220.     ELSE
  1221.         BEGIN
  1222.         fPageAreas.theMargins := newMargins;
  1223.         WITH fPageAreas DO
  1224.             BEGIN
  1225.             theInterior := thePaper;
  1226.             {$Push} {$H-}
  1227.             AddPt(theMargins.topLeft, theInterior.topLeft);
  1228.             AddPt(theMargins.botRight, theInterior.botRight);
  1229.             {$Pop}
  1230.             END;
  1231.         END;
  1232.  
  1233.     END;
  1234.  
  1235. {--------------------------------------------------------------------------------------------------}
  1236. {$S PrintNonRes}
  1237.  
  1238. PROCEDURE TStdPrintHandler.InvalPageFeedback;
  1239.  
  1240.     BEGIN
  1241.     IF ShowsOnScreen THEN
  1242.         fView.ForceRedraw;
  1243.     END;
  1244.  
  1245. {--------------------------------------------------------------------------------------------------}
  1246. {$S PrintNonRes}
  1247.  
  1248. PROCEDURE TStdPrintHandler.LocatePageInterior(pageNumber: INTEGER;
  1249.                                               VAR loc: Point); OVERRIDE;
  1250.  
  1251.     BEGIN
  1252.     WITH fPageAreas DO
  1253.         BEGIN
  1254.         loc := thePaper.topLeft;
  1255.         {$Push} {$H-}
  1256.         AddPt(theMargins.topLeft, loc);
  1257.         {$Pop}
  1258.         END;
  1259.     END;
  1260.  
  1261. {--------------------------------------------------------------------------------------------------}
  1262. {$S PrintActual}
  1263.  
  1264. FUNCTION TStdPrintHandler.MaxPageNumber: INTEGER; OVERRIDE;
  1265.  
  1266.     BEGIN
  1267.     WITH fPageStrips DO
  1268.         MaxPageNumber := fStartPage + (v * h) - 1;
  1269.     END;
  1270.  
  1271. {--------------------------------------------------------------------------------------------------}
  1272. {$S PrintActual}
  1273.  
  1274. FUNCTION TStdPrintHandler.OneSubJob(subjobFirstPage, subjobLastPage: INTEGER;
  1275.                                     justSpool: BOOLEAN;
  1276.                                     partialJob: BOOLEAN;
  1277.                                     VAR ranOutOfSpace: BOOLEAN;
  1278.                                     VAR lastPageTried: INTEGER;
  1279.                                     VAR proceed: BOOLEAN): TCommand;
  1280.  
  1281.     LABEL 1000;
  1282.  
  1283.     VAR
  1284.         pass:                INTEGER;
  1285.         noOfCopies:         INTEGER;
  1286.         aPageNumber:        INTEGER;
  1287.         err:                OSErr;
  1288.         fi:                 FailInfo;
  1289. {--------------------------------------------------------------------------------------------------}
  1290.  
  1291.     PROCEDURE FieldClientError(error: OSErr;
  1292.                                message: LONGINT);
  1293.  
  1294.         BEGIN
  1295.         proceed := FALSE;
  1296.         err := error;                                    { pass along client's error code } {Why???}
  1297.         GOTO 1000;
  1298.         END;
  1299.  
  1300.     BEGIN
  1301.     {$IFC qDebug}
  1302.     IF gDebugPrinting THEN
  1303.         WriteLn('OneSubJob entered for pages ', subjobFirstPage: 1, ' through ', subjobLastPage: 1,
  1304.                 ', proceed=', ORD(proceed): 0);
  1305.     {$ENDC}
  1306.     OneSubJob := NIL;
  1307.     ranOutOfSpace := FALSE;
  1308.     lastPageTried := subjobFirstPage - 1;
  1309.     WITH THPrint(fHPrint)^^.PrJob DO
  1310.         BEGIN
  1311.         iFstPage := 1;
  1312.         iLstPage := subjobLastPage - subjobFirstPage + 1;
  1313.  
  1314.         IF bjDocLoop = BSpoolLoop THEN
  1315.             noOfCopies := 1
  1316.         ELSE
  1317.             noOfCopies := iCopies;
  1318.         END;
  1319.     fPPrPort := PrOpenDoc(THPrint(fHPrint), NIL, NIL);
  1320.     { ??? need to allow/encourage app to supply nonNil args? }
  1321.     ChkPrintErr(err, proceed, ranOutOfSpace);
  1322.     gCurrPrintHandler := SELF;
  1323.  
  1324.     IF proceed THEN
  1325.         BEGIN
  1326.         fView.InvalidateFocus;
  1327.         gPrinting := TRUE;
  1328.         SetPort(GrafPtr(fPPrPort));
  1329.         fView.BeInPort(GrafPtr(fPPrPort));
  1330.  
  1331.         gPrinting := TRUE;
  1332.         IF NOT fView.Focus THEN
  1333.             BEGIN
  1334.             {$IFC qDebug}
  1335.             ProgramBreak('Can''t focus view while printing');
  1336.             {$ENDC}
  1337.             END;
  1338.         FOR pass := 1 TO noOfCopies DO
  1339.             BEGIN
  1340.             FOR aPageNumber := subjobFirstPage TO subjobLastPage DO
  1341.                 IF proceed THEN
  1342.                     BEGIN
  1343.                     lastPageTried := aPageNumber;
  1344.                     CatchFailures(fi, FieldClientError);
  1345.                     PrintPage(aPageNumber);
  1346.                     Success(fi);
  1347.                 1000:
  1348.                     ChkPrintErr(err, proceed, ranOutOfSpace);
  1349.                     END;
  1350.             END;
  1351.         gPrinting := FALSE;
  1352.         fView.InvalidateFocus;
  1353.         fView.BeInPort(fView.GetGrafPort);
  1354.         END;
  1355.  
  1356.     gCurrPrintHandler := NIL;
  1357.     PrCloseDoc(fPPrPort);                                { This will close the port! }
  1358.     SetPort(gWorkPort);
  1359.     ChkPrintErr(err, proceed, ranOutOfSpace);
  1360.  
  1361.     IF ranOutOfSpace THEN
  1362.         Exit(OneSubJob)
  1363.     ELSE IF proceed THEN
  1364.         BEGIN
  1365.         IF THPrint(fHPrint)^^.PrJob.bjDocLoop = BSpoolLoop THEN
  1366.             IF NOT justSpool THEN
  1367.                 PrintSpoolFile(fHPrint, err, proceed);
  1368.         END;
  1369.     IF NOT proceed THEN
  1370.         IF err <> iPrAbort THEN
  1371.             Failure(err, 0);
  1372.     END;
  1373.  
  1374. {--------------------------------------------------------------------------------------------------}
  1375. {$S PrintRes}
  1376.  
  1377. PROCEDURE TStdPrintHandler.OpenPrintShop;
  1378.  
  1379.     VAR
  1380.         err:                OSErr;
  1381.  
  1382.     BEGIN
  1383.     PrOpen;                                             { Open the print shop }
  1384.     err := PrError;                                     { Get code }
  1385.     IF err <> noErr THEN
  1386.         BEGIN
  1387.         IF (err = fnfErr) | (err = resFNotFound) THEN
  1388.             err := errNoPrintDrvr;
  1389.         Failure(err, 0);
  1390.         END;
  1391.     END;
  1392.  
  1393. {--------------------------------------------------------------------------------------------------}
  1394. {$S PrintRes}
  1395.  
  1396. FUNCTION TStdPrintHandler.PageToStrip(pageNumber: INTEGER): Point;
  1397.  
  1398.     VAR
  1399.         normalizedPageNum:    INTEGER;
  1400.         ortho:                VHSelect;
  1401.         strip:                Point;
  1402.  
  1403.     BEGIN
  1404.     normalizedPageNum := pageNumber - fStartPage + 1;
  1405.  
  1406.     ortho := gOrthogonal[fPageDirection];
  1407.  
  1408.     strip.vh[ortho] := ((normalizedPageNum - 1) DIV fPageStrips.vh[ortho]);
  1409.     strip.vh[fPageDirection] := normalizedPageNum - ((strip.vh[ortho]) * fPageStrips.vh[ortho]) - 1;
  1410.  
  1411.     PageToStrip := strip;
  1412.     END;
  1413.  
  1414. {--------------------------------------------------------------------------------------------------}
  1415. {$S PrintRes}
  1416.  
  1417. FUNCTION TStdPrintHandler.PointToPageStrip(pointInView: VPoint): Point;
  1418. { !!! Need to test this! }
  1419.  
  1420.     VAR
  1421.         loc:                INTEGER;
  1422.         automatic:            BOOLEAN;
  1423.         aStrip:             INTEGER;
  1424.         vhs:                VHSelect;
  1425.         pageStrip:            Point;
  1426.         prevBreak:            VCoordinate;
  1427.  
  1428.     BEGIN
  1429.     FOR vhs := v TO h DO
  1430.         IF fFixedSizePages[vhs] THEN
  1431.             pageStrip.vh[vhs] := (pointInView.vh[vhs] DIV fViewPerPage.vh[vhs]) + 1
  1432.         ELSE
  1433.             BEGIN
  1434.             pageStrip.vh[vhs] := 1;
  1435.             loc := fPrintExtent.topLeft.vh[vhs];        { ??? or orthogonal? }
  1436.             WHILE pointInView.vh[vhs] > loc DO            { ??? or orthogonal? }
  1437.                 BEGIN
  1438.                 IF qDebug THEN
  1439.                     prevBreak := loc;
  1440.  
  1441.                 loc := fView.DoBreakFollowing(vhs, loc, automatic);
  1442.  
  1443.                 IF qDebug & (loc <= prevBreak) THEN
  1444.                     ProgramBreak('thisBreak (loc) <= prevBreak');
  1445.  
  1446.                 pageStrip.vh[vhs] := aStrip + 1;
  1447.                 END;
  1448.             END;
  1449.     PointToPageStrip := pageStrip;
  1450.     END;
  1451.  
  1452. {--------------------------------------------------------------------------------------------------}
  1453. {$S PrintActual}
  1454.  
  1455. FUNCTION TStdPrintHandler.PoseJobDialog: BOOLEAN;
  1456.  
  1457.     VAR
  1458.         b:                    BOOLEAN;
  1459.         proceed:            BOOLEAN;
  1460.         temp:                INTEGER;
  1461.         err:                OSErr;
  1462.  
  1463.     PROCEDURE CallJobDialog;
  1464.  
  1465.         BEGIN
  1466.         SetCursor(arrow);
  1467.         IF gApplication <> NIL THEN
  1468.             gApplication.InvalidateCursorRgn;
  1469.  
  1470.         proceed := PrJobDialog(THPrint(fHPrint));
  1471.         END;
  1472.  
  1473.     BEGIN
  1474.     proceed := TRUE;
  1475.     { PrepareForDialog; }
  1476.     DoInMacPrint(CallJobDialog);
  1477.     ChkPrintErr(err, proceed, b);
  1478.  
  1479.     WITH THPrint(fHPrint)^^.PrJob DO
  1480.         IF iFstPage > iLstPage THEN                     { Rectify the range as a public service if
  1481.                                                          needed }
  1482.             BEGIN
  1483.             temp := iLstPage;
  1484.             iLstPage := iFstPage;
  1485.             iFstPage := temp;
  1486.             END;
  1487.  
  1488.     gApplication.UpdateAllWindows;
  1489.     PoseJobDialog := proceed;
  1490.     END;
  1491.  
  1492. {$S PrintActual}                                        { Needs to be here because it may be called
  1493.                                                          from Print }
  1494. {--------------------------------------------------------------------------------------------------}
  1495.  
  1496. FUNCTION TStdPrintHandler.PosePageSetupDialog(VAR proceed: BOOLEAN;
  1497.                                               isUndoable: BOOLEAN): TCommand;
  1498.  
  1499.     VAR
  1500.         react:                BOOLEAN;
  1501.         aPrintStyleChangeCommand: TPrintStyleChangeCommand;
  1502.  
  1503.     PROCEDURE CallStyleDialog;
  1504.  
  1505.         BEGIN
  1506.         SetCursor(arrow);
  1507.         IF gApplication <> NIL THEN
  1508.             gApplication.InvalidateCursorRgn;
  1509.  
  1510.         react := PrStlDialog(THPrint(fHPrint));
  1511.         END;
  1512.  
  1513.     BEGIN
  1514.     PosePageSetupDialog := NIL;
  1515.     react := FALSE;                                     { in case MacPrint code not accessible }
  1516.     IF NOT isUndoable THEN
  1517.         BEGIN
  1518.         { PrepareForDialog; }
  1519.         DoInMacPrint(CallStyleDialog);
  1520.         IF react THEN
  1521.             CheckPrinter;
  1522.         END
  1523.     ELSE
  1524.         BEGIN
  1525.   { Must setup command before putting up page setup dialog because the
  1526.    command records the current print record to make it undoable. }
  1527.         New(aPrintStyleChangeCommand);
  1528.         FailNIL(aPrintStyleChangeCommand);
  1529.         aPrintStyleChangeCommand.IPrintStyleChangeCommand(SELF);
  1530.  
  1531.         { PrepareForDialog; }
  1532.         DoInMacPrint(CallStyleDialog);                    { Put up the Page Setup Dialog }
  1533.  
  1534.         IF react THEN                                    { User specified a change }
  1535.             BEGIN
  1536.             BlockMove(fHPrint^, aPrintStyleChangeCommand.fNewHPrint^, SIZEOF(TPrint));
  1537.             PosePageSetupDialog := aPrintStyleChangeCommand;
  1538.             END
  1539.  
  1540.         ELSE                                            { User did not specify a change }
  1541.             BEGIN
  1542.             FreeIfObject(aPrintStyleChangeCommand);
  1543.             aPrintStyleChangeCommand := NIL;
  1544.             END;
  1545.  
  1546.         END;
  1547.     proceed := react;
  1548.     END;
  1549.  
  1550. {--------------------------------------------------------------------------------------------------}
  1551. {$S PrintActual}
  1552.  
  1553. PROCEDURE TStdPrintHandler.PosePrintDialog;
  1554.  
  1555.     VAR
  1556.         dlgNumber:            INTEGER;
  1557.         dlogTemplate:        DialogTHndl;
  1558.         docName:            Str255;
  1559.         itemNo:             INTEGER;
  1560.         theItem:            Handle;
  1561.         itemType:            INTEGER;
  1562.         box:                Rect;
  1563.         itemText:            Str255;
  1564.         preDocName, constTitle: INTEGER;
  1565.  
  1566.     BEGIN
  1567.     IF gFinderPrinting THEN
  1568.         BEGIN
  1569.         dlgNumber := phFinderPrintDialog;
  1570.         itemNo := 3;
  1571.         END
  1572.     ELSE
  1573.         BEGIN
  1574.         dlgNumber := phSpoolPrintDialog;
  1575.         itemNo := 2;
  1576.         END;
  1577.  
  1578.     { Can't use GetNewCenteredDialog because vertically centering the dialog may cause it
  1579.       to interfere with the Print Manager's status windows.  Therefore, leave the vertical
  1580.       location of the dialog fixed. }
  1581.  
  1582.     SetCursor(arrow);
  1583.     gApplication.InvalidateCursorRgn;
  1584.     dlogTemplate := DialogTHndl(GetResource('DLOG', dlgNumber));
  1585.     IF dlogTemplate <> NIL THEN
  1586.         BEGIN
  1587.         CenterRectOnScreen(dlogTemplate^^.boundsRect, TRUE, FALSE, FALSE);
  1588.         fPrintDialog := GetNewDialog(dlgNumber, NIL, POINTER( - 1));
  1589.         FailNIL(fPrintDialog);
  1590.         END
  1591.     ELSE
  1592.         BEGIN
  1593.         {$IFC qDebug}
  1594.         WriteLn('You may have forgotten to include Printing.rsrc in your .r file…');
  1595.         ProgramBreak('The print job dialog resource can''t be found.');
  1596.         {$ENDC}
  1597.         FailNilResource(dlogTemplate);
  1598.         END;
  1599.  
  1600.  { Substitute the document name for '<<<>>>' in 'Document “<<<>>>” is being printed'.
  1601.   ParamText would be a lot simpler, but the Print Mgr. also uses ParamText, and
  1602.   the substitution doesn't happen until draw time.}
  1603.     GetDocName(docName);
  1604.     GetDItem(fPrintDialog, itemNo, itemType, theItem, box);
  1605.     IF theItem <> NIL THEN
  1606.         BEGIN
  1607.         GetIText(theItem, itemText);
  1608.         IF ParseTitleTemplate(itemText, preDocName, constTitle) & SubstituteInTitle(itemText,
  1609.            docName, preDocName, constTitle) THEN
  1610.             SetIText(theItem, itemText);
  1611.         END;
  1612.  
  1613.     THPrint(fHPrint)^^.PrJob.pIdleProc := @IdleProcForTStdPrintHandler;
  1614.     SetWTitle(fPrintDialog, docName);                    { In case Print Mgr. needs it. }
  1615.     DrawDialog(fPrintDialog);
  1616.     END;
  1617.  
  1618. {--------------------------------------------------------------------------------------------------}
  1619. {$S PrintRes}
  1620. { ???Was in PrintActual.  Doesn't really belong in this segment, but
  1621.  can get unloaded during Finder printing otherwise. }
  1622.  
  1623. FUNCTION TStdPrintHandler.Print(itsCmdNumber: CmdNumber;
  1624.                                 VAR proceed: BOOLEAN): TCommand; OVERRIDE;
  1625.  
  1626.     VAR
  1627.         fi:                 FailInfo;
  1628.  
  1629.     PROCEDURE DoPrint;
  1630.  
  1631.         VAR
  1632.             firstPage:            INTEGER;
  1633.             lastPage:            INTEGER;
  1634.             err:                OSErr;
  1635.             spoolFileName:        Str255;
  1636.             spoolVRefNum:        INTEGER;
  1637.             aPrJob:             TPrJob;
  1638.             totalPages:         INTEGER;
  1639.             lastPrinted:        INTEGER;
  1640.             lastAttempted:        INTEGER;
  1641.             pagesPerSubjob:     INTEGER;
  1642.             firstSubjobPage:    INTEGER;
  1643.             proceed:            BOOLEAN;
  1644.             ranOutOfSpace:        BOOLEAN;
  1645.             spoolMethod:        BOOLEAN;
  1646.             justSpool:            BOOLEAN;
  1647.             dontCare:            BOOLEAN;
  1648.             pageStrips:         Point;
  1649.             fi:                 FailInfo;
  1650.  
  1651.         PROCEDURE HdlSubjobFailure(error: OSErr;
  1652.                                    message: LONGINT);
  1653.  
  1654.             BEGIN
  1655.             BanishPrintDialog;
  1656.             END;
  1657.  
  1658.         BEGIN
  1659.         gJobPrintHandler := SELF;                        { be visible to the idleProc }
  1660.         justSpool := (itsCmdNumber = cPrintToFile);
  1661.         proceed := TRUE;
  1662.         ranOutOfSpace := FALSE;
  1663.         aPrJob := THPrint(fHPrint)^^.PrJob;
  1664.         fView.DoCalcPageStrips(pageStrips);
  1665.         fPageStrips := pageStrips;
  1666.  
  1667.         firstPage := MAX(aPrJob.iFstPage, fStartPage);
  1668.         lastPage := Min(aPrJob.iLstPage, MaxPageNumber);
  1669.  
  1670.         IF lastPage < firstPage THEN
  1671.             err := Alert(phNoPages, NIL)
  1672.         ELSE
  1673.             BEGIN
  1674.             totalPages := lastPage - firstPage + 1;
  1675.             spoolMethod := (aPrJob.bjDocLoop = BSpoolLoop);
  1676.             IF spoolMethod THEN
  1677.                 BEGIN
  1678.                 ChooseSpoolFile(spoolFileName, spoolVRefNum, pagesPerSubjob);
  1679.                 IF NOT justSpool THEN                    { if justSpool is true, then the spool
  1680.                                                          filename & vRefNum will already have been
  1681.                                                          stuffed into the prJob record before this
  1682.                                                          method is called }
  1683.                     BEGIN
  1684.                     IF spoolFileName <> '' THEN
  1685.                         WITH THPrint(fHPrint)^^.PrJob DO
  1686.                             BEGIN
  1687.                             pFileName := @spoolFileName;
  1688.                             iFileVol := spoolVRefNum;
  1689.                             END;
  1690.                     END;
  1691.                 END
  1692.             ELSE
  1693.                 pagesPerSubjob := MAXINT;
  1694.  
  1695.             lastPrinted := firstPage - 1;
  1696.  
  1697.             pagesPerSubjob := Min(pagesPerSubjob, totalPages);
  1698.             PosePrintDialog;
  1699.  
  1700.             CatchFailures(fi, HdlSubjobFailure);
  1701.             REPEAT
  1702.                 firstSubjobPage := lastPrinted + 1;
  1703.                 Print := OneSubJob(firstSubjobPage, firstSubjobPage + pagesPerSubjob - 1, justSpool,
  1704.                                    (pagesPerSubjob < totalPages), ranOutOfSpace, lastAttempted,
  1705.                                    proceed);
  1706.                 IF proceed THEN
  1707.                     lastPrinted := lastAttempted;
  1708.                 IF ranOutOfSpace THEN
  1709.                     BEGIN
  1710.                     pagesPerSubjob := lastAttempted - 1 - firstSubjobPage;
  1711.                     proceed := TRUE;
  1712.                     END;
  1713.             UNTIL (lastPrinted = lastPage) | (pagesPerSubjob < 1) | NOT proceed;
  1714.  
  1715.             IF pagesPerSubjob < 1 THEN
  1716.                 Failure(errSpooling, 0);
  1717.             Success(fi);
  1718.             BanishPrintDialog;                            { having removed, put back here, unsure if
  1719.                                                          exactly right }
  1720.             END;                                        { if there are pages within requested range
  1721.                                                          }
  1722.  
  1723.         gJobPrintHandler := NIL;                        { out damned spot }
  1724.         END;
  1725.  
  1726. {--------------------------------------------------------------------------------------------------}
  1727.  
  1728.     PROCEDURE HdlPrintFailure(error: OSErr;
  1729.                               message: LONGINT);
  1730.  
  1731.         BEGIN
  1732.   { Certain Print Manager errors should not result in any alert,
  1733.    since the Print Manager will have already put one up. }
  1734.         IF (error >= - 8160) & (error <= - 8150) THEN
  1735.             Failure(0, msgPrintFailed);
  1736.         IF message = 0 THEN
  1737.             GetDocName(gErrorParm3);
  1738.         FailNewMessage(error, message, msgPrintFailed);
  1739.         END;
  1740.  
  1741.     BEGIN                                                { TStdPrintHandler.Print }
  1742.     Print := NIL;
  1743.     gCancelAllPrinting := FALSE;
  1744.  
  1745.     SetPrintExtent;                                     { Make sure we've got the right area. }
  1746.  
  1747.     CatchFailures(fi, HdlPrintFailure);
  1748.     DoInMacPrint(DoPrint);
  1749.     Success(fi);
  1750.     proceed := NOT gCancelAllPrinting;
  1751.     END;
  1752.  
  1753. {--------------------------------------------------------------------------------------------------}
  1754. {$S PrintNonRes}
  1755.  
  1756. PROCEDURE TStdPrintHandler.PrinterChanged; OVERRIDE;
  1757.  
  1758.     BEGIN
  1759.     fView.DoPagination;
  1760.     END;
  1761.  
  1762. {--------------------------------------------------------------------------------------------------}
  1763. {$S PrintImage}
  1764.  
  1765. PROCEDURE TStdPrintHandler.PrintPage(aPageNumber: INTEGER); { Print a single page }
  1766.  
  1767.     VAR
  1768.         {$IFC qDebug}
  1769.         aPort:                GrafPtr;
  1770.         {$ENDC}
  1771.         fi:                 FailInfo;
  1772.  
  1773.     PROCEDURE CheckPrintFailure;
  1774.  
  1775.         BEGIN
  1776.         FailOSErr(PrError);
  1777.         END;
  1778.  
  1779.     PROCEDURE HdlPrintFailure(error: OSErr;
  1780.                               message: LONGINT);
  1781.  
  1782.         BEGIN
  1783.         PrClosePage(fPPrPort);
  1784.         END;
  1785.  
  1786.     BEGIN
  1787.     SetPage(aPageNumber);                                { gets gPage set up correctly for coordinate
  1788.                                                          transformations }
  1789.     CatchFailures(fi, HdlPrintFailure);
  1790.     PrOpenPage(fPPrPort, NIL);
  1791.     CheckPrintFailure;
  1792.     FocusOnInterior;
  1793.     DrawPageInterior;
  1794.     {$IFC qDebug}
  1795.     GetPort(aPort);
  1796.     IF aPort <> GrafPtr(fPPrPort) THEN
  1797.         ProgramBreak('The view''s DrawPageInterior method changed the grafPort');
  1798.     {$ENDC}
  1799.     CheckPrintFailure;
  1800.     FocusOnBorder;
  1801.     AdornPage;
  1802.     CheckPrintFailure;
  1803.     Success(fi);
  1804.     PrClosePage(fPPrPort);
  1805.     END;
  1806.  
  1807. {--------------------------------------------------------------------------------------------------}
  1808. {$S PrintNonRes}
  1809.  
  1810. PROCEDURE TStdPrintHandler.RedoPageBreaks; OVERRIDE;
  1811. { Called from fView.DoPagination. }
  1812.  
  1813.     VAR
  1814.         worryAboutBreaks:    BOOLEAN;
  1815.         oldViewPerPage, viewPerPage: VPoint;
  1816.         pageStrips:         Point;
  1817.         newInterior, oldInterior: Rect;
  1818.  
  1819.     BEGIN
  1820.     worryAboutBreaks := (fView.GetGrafPort <> NIL) & gInitialized & (fShowBreaks | gDebugPrinting);
  1821.  
  1822.     IF worryAboutBreaks THEN
  1823.         InvalPageFeedback;                                { invalidate old page breaks, if relevant }
  1824.  
  1825.     SetPrintExtent;
  1826.     oldInterior := fPageAreas.theInterior;
  1827.     oldViewPerPage := fViewPerPage;
  1828.     SetMargins;
  1829.  
  1830.   { computes view per page from papersize, printer resolution, margins desired, view resolution,
  1831.    and, if desired, other factors such as printable rectangle of page and font metrics in the
  1832.    printer space }
  1833.     fView.DoCalcViewPerPage(viewPerPage);
  1834.     fViewPerPage := viewPerPage;
  1835.     SetPageInterior(kUsualPages);
  1836.     newInterior := fPageAreas.theInterior;
  1837.  
  1838.     {$IFC qDebug}
  1839.     IF gDebugPrinting THEN
  1840.         IF NOT EqualRect(oldInterior, newInterior) THEN
  1841.             ProgramBreak('Setting new interior');
  1842.     {$ENDC}
  1843.  
  1844.     IF NOT EqualRect(oldInterior, newInterior) THEN
  1845.         fView.PageInteriorChanged(newInterior);
  1846.  
  1847.     {$IFC qDebug}
  1848.     IF gDebugPrinting THEN
  1849.         IF NOT EqualVPt(oldViewPerPage, viewPerPage) THEN
  1850.             ProgramBreak('Setting new view per page');
  1851.     {$ENDC}
  1852.  
  1853.     IF NOT EqualRect(oldInterior, newInterior) | NOT EqualVPt(oldViewPerPage, viewPerPage) THEN
  1854.         fView.AdjustSize;
  1855.  
  1856.     fView.DoCalcPageStrips(pageStrips);
  1857.     fPageStrips := pageStrips;
  1858.  
  1859.     IF worryAboutBreaks THEN
  1860.         InvalPageFeedback;                                { force redraw of new page breaks, if
  1861.                                                          relevant }
  1862.  
  1863.     END;
  1864.  
  1865. {--------------------------------------------------------------------------------------------------}
  1866. {$S PrintNonRes}
  1867.  
  1868. PROCEDURE TStdPrintHandler.Reset;
  1869. { subclass may stuff some special values by redefining this }
  1870.  
  1871.     LABEL 1000;
  1872.  
  1873.     TYPE
  1874.         TXWord                = PACKED RECORD
  1875.             CASE INTEGER OF
  1876.                 0:
  1877.                     (c1, c0:             CHAR);
  1878.                 1:
  1879.                     (b1, b0:             SignedByte);
  1880.                 2:
  1881.                     (f15, f14, f13, f12, f11, f10, f9, f8, f7, f6, f5, f4, f3, f2, f1, f0: BOOLEAN);
  1882.                 3:
  1883.                     (i0:                 INTEGER);
  1884.             END;
  1885.  
  1886.     VAR
  1887.         anHPrint:            THPrint;
  1888.         didChange:            BOOLEAN;
  1889.         inited:             BOOLEAN;
  1890.         fi:                 FailInfo;
  1891.  
  1892.     PROCEDURE CallPrintDefault;
  1893.  
  1894.         BEGIN
  1895.         PrintDefault(anHPrint);
  1896.         END;
  1897.  
  1898.     PROCEDURE HdlDefaultError(error: OSErr;
  1899.                               message: LONGINT);
  1900.  
  1901.         BEGIN
  1902.         GOTO 1000;
  1903.         END;
  1904.  
  1905.     BEGIN
  1906.     anHPrint := THPrint(fHPrint);
  1907.     inited := FALSE;
  1908.     IF anHPrint <> NIL THEN
  1909.         BEGIN
  1910.         IF gCouldPrint THEN
  1911.             BEGIN
  1912.             CatchFailures(fi, HdlDefaultError);
  1913.             DoInMacPrint(CallPrintDefault);
  1914.             IF fSquareDots THEN
  1915.                 WITH TXWord(THPrint(anHPrint)^^.prStl.wDev) DO
  1916.                     IF b1 = 1 THEN                        { 1 = bDevCItoh => ImageWriter }
  1917.                         BEGIN
  1918.    { Set the square-pixel flag in the print record, then
  1919.  ensure we didn't corrupt it. }
  1920.                         f2 := TRUE;
  1921.                         ValidatePrintRecord(didChange);
  1922.                         END;
  1923.             inited := TRUE;
  1924.             Success(fi);
  1925.             END;
  1926.     1000:
  1927.         IF NOT (gCouldPrint & inited) THEN
  1928.    { MacPrint code unavailable, but we want some plausible things
  1929.  anyway - set up for Portrait Tall Adj. }
  1930.             BEGIN
  1931.    { ??? Replace the following expensive stuffing code with StuffHex
  1932.  calls or a GetResource or some such, later }
  1933.             WITH anHPrint^^ DO
  1934.             {$Push} {$H-}
  1935.                 BEGIN
  1936.                 iPrVersion := 0;                        { something invalid }
  1937.  
  1938.                 WITH prInfo DO
  1939.                     BEGIN
  1940.                     iHRes := 72;
  1941.                     iVRes := 72;
  1942.                     SetRect(rPage, 0, 0, 576, 752);     { must have its top left @ (0,0) }
  1943.                     END;
  1944.  
  1945.                 SetRect(rPaper, - 18, - 36, 594, 756);
  1946.  
  1947.                 WITH prStl DO
  1948.                     BEGIN
  1949.                     iPageV := 1320;                     { 11 inches in 120th of an inch }
  1950.                     iPageH := 1020;                     { 8.5 inches in 120th of an inch }
  1951.                     END;
  1952.                 {$Pop}
  1953.                 END;
  1954.             END;
  1955.  
  1956.         END;
  1957.     END;
  1958.  
  1959. {--------------------------------------------------------------------------------------------------}
  1960. {$S PrintNonRes}
  1961.  
  1962. PROCEDURE TStdPrintHandler.SetPrintExtent;
  1963.  
  1964.     VAR
  1965.         printExtent:        VRect;
  1966.  
  1967.     BEGIN
  1968.     fView.GetPrintExtent(printExtent);
  1969.  { Make sure the bottom or right is not smaller than the top or left.
  1970.   This can happen when views are being created and before the window
  1971.   has been resized to its actual size. }
  1972.     printExtent.bottom := MAX(printExtent.bottom, printExtent.top);
  1973.     printExtent.right := MAX(printExtent.right, printExtent.left);
  1974.     fPrintExtent := printExtent;
  1975.     END;
  1976.  
  1977. {--------------------------------------------------------------------------------------------------}
  1978. {$S PrintOpen}
  1979.  
  1980. PROCEDURE TStdPrintHandler.SetDefaultPrintInfo;
  1981.  
  1982.     VAR
  1983.         didChange:            BOOLEAN;
  1984.         wantValidate:        BOOLEAN;
  1985.         anHPrint:            THPrint;
  1986.         haveHPrint:         BOOLEAN;
  1987.  
  1988.     BEGIN
  1989.     fHPrint := DisposeIfHandle(fHPrint);
  1990.     wantValidate := FALSE;
  1991.  
  1992.     haveHPrint := FALSE;
  1993.     IF fView <> NIL THEN
  1994.         BEGIN
  1995.         IF fDocument <> NIL THEN
  1996.             IF fDocument.fSharePrintInfo & (fDocument.fPrintInfo <> NIL) THEN
  1997.                 BEGIN
  1998.                 fHPrint := fDocument.fPrintInfo;
  1999.                 haveHPrint := TRUE;
  2000.                 END;
  2001.         END;
  2002.  
  2003.     IF haveHPrint THEN
  2004.         wantValidate := TRUE
  2005.     ELSE
  2006.         BEGIN
  2007.         fHPrint := NewPermHandle(SIZEOF(TPrint));
  2008.         FailNIL(fHPrint);
  2009.         Reset;
  2010.         END;
  2011.  
  2012.     IF wantValidate THEN
  2013.         ValidatePrintRecord(didChange);
  2014.     END;
  2015.  
  2016. {--------------------------------------------------------------------------------------------------}
  2017. {$S PrintNonRes}
  2018.  
  2019. PROCEDURE TStdPrintHandler.SetMargins;
  2020.  
  2021.     VAR
  2022.         someMargins:        Rect;
  2023.  
  2024.     BEGIN
  2025.     someMargins := fPageAreas.theMargins;                { Prevent heap scramble }
  2026.     InstallMargins(someMargins, fMinimalMargins);
  2027.     END;
  2028.  
  2029. {--------------------------------------------------------------------------------------------------}
  2030. {$S PrintImage}
  2031.  
  2032. PROCEDURE TStdPrintHandler.SetPage(aPageNumber: INTEGER);
  2033.  
  2034.     VAR
  2035.         viewedRect:         VRect;
  2036.         vhs:                VHSelect;
  2037.         strip:                Point;
  2038.         {$IFC qDebug}
  2039.         aRect:                Rect;
  2040.         {$ENDC}
  2041.  
  2042.     BEGIN
  2043.     fFocusedPage := aPageNumber;
  2044.  
  2045.     strip := PageToStrip(aPageNumber);
  2046.     FOR vhs := v TO h DO
  2047.         BEGIN
  2048.         GetBreakCoord(gOrthogonal[vhs], strip.vh[vhs], viewedRect.topLeft.vh[vhs]);
  2049.         GetBreakCoord(gOrthogonal[vhs], strip.vh[vhs] + 1, viewedRect.botRight.vh[vhs]);
  2050.         END;
  2051.  
  2052.     SetPageInterior(aPageNumber);
  2053.     fView.DoSetPageOffset(viewedRect.topLeft);
  2054.     fViewedRect := viewedRect;
  2055.  
  2056.     {$IFC qDebug}
  2057.     IF gDebugPrinting THEN
  2058.         BEGIN
  2059.         Write('pg #: ', aPageNumber: 1);
  2060.         Write(';  coord = ');
  2061.         WriteVPt(viewedRect.topLeft);
  2062.         Write('Page Interior: ');
  2063.         aRect := fPageAreas.theInterior;
  2064.         WriteRect(aRect);                                { ???HS }
  2065.         WriteLn;
  2066.         END;
  2067.     {$ENDC}
  2068.     END;
  2069.  
  2070. {--------------------------------------------------------------------------------------------------}
  2071. {$S PrintNonRes}
  2072.  
  2073. PROCEDURE TStdPrintHandler.SetPageInterior(pageNumber: INTEGER); OVERRIDE;
  2074.  
  2075.     VAR
  2076.         vhs:                VHSelect;
  2077.         pegPoint:            Point;
  2078.  
  2079.     BEGIN
  2080.     WITH fPageAreas, theInterior DO
  2081.         BEGIN
  2082.         FOR vhs := v TO h DO
  2083.             BEGIN
  2084.             topLeft.vh[vhs] := thePaper.topLeft.vh[vhs] + theMargins.topLeft.vh[vhs];
  2085.             botRight.vh[vhs] := topLeft.vh[vhs] + fViewPerPage.vh[vhs];
  2086.             END;
  2087.         END;
  2088.  
  2089.     LocatePageInterior(pageNumber, pegPoint);
  2090.     WITH fPageAreas.theInterior DO
  2091.         BEGIN
  2092.         topLeft := pegPoint;
  2093.         FOR vhs := v TO h DO
  2094.             botRight.vh[vhs] := topLeft.vh[vhs] + fViewPerPage.vh[vhs];
  2095.         END;
  2096.     END;
  2097.  
  2098. {--------------------------------------------------------------------------------------------------}
  2099. {$S PrintImage}
  2100.  
  2101. PROCEDURE TStdPrintHandler.SetPageOffset(coord: VPoint); OVERRIDE;
  2102.  
  2103.     VAR
  2104.         vhs:                VHSelect;
  2105.  
  2106.     BEGIN
  2107.     FOR vhs := v TO h DO
  2108.         gPageOffset.vh[vhs] := coord.vh[vhs] - fPageAreas.theInterior.topLeft.vh[vhs];
  2109.     END;
  2110.  
  2111. {--------------------------------------------------------------------------------------------------}
  2112. {$S PrintFinder}
  2113.  
  2114. FUNCTION TStdPrintHandler.SetupForFinder: BOOLEAN; OVERRIDE;
  2115.  
  2116.     VAR
  2117.         proceed:            BOOLEAN;
  2118.         didChange:            BOOLEAN;
  2119.  
  2120.     BEGIN
  2121.     proceed := TRUE;
  2122.     CheckPrinter;                                        { Uncertain if necessary??? }
  2123.  
  2124.     IF fFinderSetup THEN
  2125.         IF PosePageSetupDialog(proceed, FALSE) <> NIL THEN
  2126.         {$IFC qDebug}
  2127.             ProgramBreak('PosePageSetupDialog returned real command.')
  2128.             {$ENDC} ;
  2129.  
  2130.     IF proceed THEN
  2131.         BEGIN
  2132.         ShowDocBeingPrinted(TRUE);
  2133.  
  2134.         IF fFinderJobDialog | (gFinderHPrint = NIL) THEN
  2135.             BEGIN
  2136.             proceed := PoseJobDialog;
  2137.             { Merge into gPrintHandler, in case next document needs it }
  2138.             IF gFinderHPrint = NIL THEN
  2139.                 BEGIN
  2140.                 gFinderHPrint := NewPermHandle(SIZEOF(TPrint));
  2141.                 FailNIL(gFinderHPrint);
  2142.                 END;
  2143.             BlockMove(fHPrint^, gFinderHPrint^, SIZEOF(TPrint));
  2144.             END
  2145.         ELSE
  2146.             BEGIN
  2147.             PrJobMerge(THPrint(gFinderHPrint), THPrint(fHPrint));
  2148.             ValidatePrintRecord(didChange);
  2149.             END;
  2150.  
  2151.         ShowDocBeingPrinted(FALSE);
  2152.         END;
  2153.     SetupForFinder := proceed;
  2154.     END;
  2155.  
  2156. {--------------------------------------------------------------------------------------------------}
  2157. {$S PrintRes}
  2158.  
  2159. FUNCTION TStdPrintHandler.SetupPrintOne: BOOLEAN;
  2160.  
  2161.     VAR
  2162.         didChange:            BOOLEAN;
  2163.  
  2164.     BEGIN
  2165.  { Call PrValidate to 1) make sure the record is OK, and
  2166.   2) Get the LaserWriter driver to get the name of the
  2167.   front window. }
  2168.     ValidatePrintRecord(didChange);
  2169.  
  2170.     PrSetError(noErr);
  2171.     WITH THPrint(fHPrint)^^.PrJob DO
  2172.         BEGIN
  2173.         iFstPage := 0;
  2174.         iLstPage := 9999;                                { This is what the Print Mgr. uses }
  2175.         END;
  2176.     SetupPrintOne := TRUE;                                { Should always be able to continue from
  2177.                                                          here }
  2178.     END;
  2179.  
  2180. {--------------------------------------------------------------------------------------------------}
  2181. {$S PrintFinder}
  2182.  
  2183. PROCEDURE TStdPrintHandler.ShowDocBeingPrinted(entering: BOOLEAN);
  2184.  
  2185.     VAR
  2186.         aTitle:             Str255;
  2187.  
  2188.     BEGIN
  2189.     IF entering THEN
  2190.         BEGIN
  2191.         fPrintDialog := GetNewDialog(phWhichDoc, NIL, POINTER( - 1));
  2192.         IF fPrintDialog <> NIL THEN
  2193.             BEGIN
  2194.             GetDocName(aTitle);
  2195.             SetWTitle(fPrintDialog, aTitle);
  2196.             DrawDialog(fPrintDialog);
  2197.             END
  2198.             {$IFC qDebug}
  2199.         ELSE
  2200.             ProgramBreak(ConcatNumber('Unable to load dialog ', phWhichDoc))
  2201.             {$ENDC}                                     { semicolon } ;
  2202.         END
  2203.     ELSE
  2204.         BanishPrintDialog;
  2205.     END;
  2206.  
  2207. {--------------------------------------------------------------------------------------------------}
  2208. {$S PrintRes}
  2209.  
  2210. FUNCTION TStdPrintHandler.ShowsOnScreen: BOOLEAN;
  2211.  
  2212.     BEGIN
  2213.     IF fView <> NIL THEN
  2214.         ShowsOnScreen := fView.GetWindow <> NIL
  2215.     ELSE
  2216.         ShowsOnScreen := FALSE;
  2217.     END;
  2218.  
  2219. {--------------------------------------------------------------------------------------------------}
  2220. {$S PrintRes}
  2221.  
  2222. FUNCTION TStdPrintHandler.StripToPage(hStrip, vStrip: INTEGER): INTEGER;
  2223.  
  2224.     VAR
  2225.         strip:                Point;
  2226.         ortho:                VHSelect;
  2227.  
  2228.     BEGIN
  2229.     SetPt(strip, hStrip, vStrip);
  2230.     ortho := gOrthogonal[fPageDirection];
  2231.     StripToPage := strip.vh[fPageDirection] * fPageStrips.vh[ortho] + strip.vh[ortho] + fStartPage;
  2232.     END;
  2233.  
  2234. {--------------------------------------------------------------------------------------------------}
  2235. {$S PrintRes}
  2236.  
  2237. PROCEDURE TStdPrintHandler.ValidatePrintRecord(VAR didChange: BOOLEAN);
  2238.  
  2239.     VAR
  2240.         fi:                 FailInfo;
  2241.  
  2242.     PROCEDURE CallPrValidate;
  2243.  
  2244.         BEGIN
  2245.         didChange := PrValidate(THPrint(fHPrint));
  2246.         END;
  2247.  
  2248.     PROCEDURE HdlValidateFailed(error: OSErr;
  2249.                                 message: LONGINT);
  2250.  
  2251.         BEGIN
  2252.         Reset;
  2253.         Exit(ValidatePrintRecord);
  2254.         END;
  2255.  
  2256.     BEGIN
  2257.     CatchFailures(fi, HdlValidateFailed);
  2258.     DoInMacPrint(CallPrValidate);
  2259.     Success(fi);
  2260.     END;
  2261.  
  2262. {--------------------------------------------------------------------------------------------------}
  2263. {$S PrintDoCommand}
  2264.  
  2265. PROCEDURE TPrintStyleChangeCommand.IPrintStyleChangeCommand(itsPrintHandler: TStdPrintHandler);
  2266.  
  2267.     VAR
  2268.         fi:                 FailInfo;
  2269.  
  2270.     PROCEDURE HdlInitFailed(error: OSErr;
  2271.                             message: LONGINT);
  2272.  
  2273.         BEGIN
  2274.         Free;
  2275.         END;
  2276.  
  2277.     BEGIN
  2278.     fStdPrintHandler := itsPrintHandler;
  2279.     fOldHPrint := NIL;
  2280.     fNewHPrint := NIL;
  2281.     ICommand(cChangePrinterStyle, itsPrintHandler.fDocument, itsPrintHandler.fView, NIL);
  2282.     fCausesChange := (fChangedDocument <> NIL) & (fChangedDocument.fSavePrintInfo);
  2283.     CatchFailures(fi, HdlInitFailed);
  2284.     fOldHPrint := NewPermHandle(SIZEOF(TPrint));
  2285.     FailNIL(fOldHPrint);
  2286.     { Make a copy of the old version of the PrintInfo record }
  2287.     BlockMove(itsPrintHandler.fHPrint^, fOldHPrint^, SIZEOF(TPrint));
  2288.     fNewHPrint := NewPermHandle(SIZEOF(TPrint));
  2289.     FailNIL(fNewHPrint);
  2290.     Success(fi);
  2291.     END;
  2292.  
  2293. {--------------------------------------------------------------------------------------------------}
  2294. {$S PrintDoCommand}
  2295.  
  2296. PROCEDURE TPrintStyleChangeCommand.Free; OVERRIDE;
  2297.  
  2298.     BEGIN
  2299.     fOldHPrint := DisposeIfHandle(fOldHPrint);
  2300.     fNewHPrint := DisposeIfHandle(fNewHPrint);
  2301.     INHERITED Free;
  2302.     END;
  2303.  
  2304. {--------------------------------------------------------------------------------------------------}
  2305. {$S PrintDoCommand}
  2306.  
  2307. PROCEDURE TPrintStyleChangeCommand.DoIt; OVERRIDE;
  2308.  
  2309.     BEGIN
  2310.     fStdPrintHandler.CheckPrinter;                        { Will find it changed, and hence dispatch
  2311.                                                          to view's DoPrinterChanged }
  2312.     END;
  2313.  
  2314. {--------------------------------------------------------------------------------------------------}
  2315. {$S PrintFields}
  2316.  
  2317. PROCEDURE TPrintStyleChangeCommand.Fields(PROCEDURE
  2318.                                           DoToField(fieldName: Str255;
  2319.                                                     fieldAddr: Ptr;
  2320.                                                     fieldType: INTEGER));
  2321.  
  2322.     BEGIN
  2323.     DoToField('TPrintStyleChangeCommand', NIL, bClass);
  2324.     DoToField('fStdPrintHandler', @fStdPrintHandler, bObject);
  2325.     DoToField('fOldHPrint', @fOldHPrint, bHandle);
  2326.     DoToField('fNewHPrint', @fNewHPrint, bHandle);
  2327.     INHERITED Fields(DoToField);
  2328.     END;
  2329.  
  2330. {--------------------------------------------------------------------------------------------------}
  2331. {$S PrintDoCommand}
  2332.  
  2333. PROCEDURE TPrintStyleChangeCommand.UndoIt; OVERRIDE;
  2334.  
  2335.     BEGIN
  2336.     BlockMove(fOldHPrint^, fStdPrintHandler.fHPrint^, SIZEOF(TPrint));
  2337.     fStdPrintHandler.CheckPrinter;                        { Will find it changed, and hence dispatch
  2338.                                                          to view's DoPrinterChanged }
  2339.     END;
  2340.  
  2341. {--------------------------------------------------------------------------------------------------}
  2342. {$S PrintDoCommand}
  2343.  
  2344. PROCEDURE TPrintStyleChangeCommand.RedoIt; OVERRIDE;
  2345.  
  2346.     BEGIN
  2347.     BlockMove(fNewHPrint^, fStdPrintHandler.fHPrint^, SIZEOF(TPrint));
  2348.     fStdPrintHandler.CheckPrinter;                        { Will find it changed, and hence dispatch
  2349.                                                          to view's DoPrinterChanged }
  2350.     END;
  2351.